package cn.flying.cloud.flow.core.listener.handler;

import javax.annotation.Resource;

import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import cn.flying.cloud.base.common.utils.Ft;
import cn.flying.cloud.flow.bo.FwTaskCandidateBo;
import cn.flying.cloud.flow.service.FwTaskCandidateService;
import cn.flying.cloud.system.api.UserServiceApi;
import cn.flying.cloud.system.model.Position;
import cn.flying.cloud.system.model.Role;
import cn.flying.cloud.system.model.User;

/**
 * @author: admin
 * @date: 2025年04月02日 21:12
 * @version: 1.0
 */
@Component
public class UserHandler {

    @DubboReference
    private UserServiceApi userServiceApi;
    @Resource
    private FwTaskCandidateService taskCandidateService;

    public Set<String> findUserByPostId(String postId) {
        Position position = userServiceApi.findPositionByPostId(postId);
        Set<String> set = position.getUsers().stream().map(User::getUserId).collect(Collectors.toSet());
        if (CollectionUtils.isEmpty(set)) {
            return new HashSet<>();
        }
        return set;
    }

    public Set<String> findUserByPostIds(String[] postIds) {
        List<Position> positions = userServiceApi.findPositionByPostIds(Arrays.asList(postIds));
        Set<String> set = positions.stream()
                .map(Position::getUsers)
                .map(users -> users.stream().map(User::getUserId).collect(Collectors.toSet())).flatMap(Set::stream).collect(Collectors.toSet());
        if (CollectionUtils.isEmpty(set)) {
            return new HashSet<>();
        }
        return set;
    }

    public Set<String> findUserByRoleId(String roleId) {
        Role role = userServiceApi.findRoleByRoleId(roleId);
        Set<String> set = role.getUsers().stream().map(User::getUserId).collect(Collectors.toSet());
        if (CollectionUtils.isEmpty(set)) {
            return new HashSet<>();
        }
        return set;
    }

    public Set<String> findUserByRoleIds(String[] roleIds) {
        List<Role> roles = userServiceApi.findRoleByRoleIds(Arrays.asList(roleIds));
        Set<String> set = roles.stream()
                .map(Role::getUsers)
                .map(users -> users.stream().map(User::getUserId).collect(Collectors.toSet())).flatMap(Set::stream).collect(Collectors.toSet());
        if (CollectionUtils.isEmpty(set)) {
            return new HashSet<>();
        }
        return set;
    }

    /**
     * 获取代理人
     *
     * @param procDefId
     * @param nodeId
     * @return
     */
    public String getAssignee(String procDefId, String nodeId) {
        FwTaskCandidateBo candidate = new FwTaskCandidateBo();
        candidate.setProcDefId(procDefId);
        candidate.setNodeId(nodeId);
        candidate = taskCandidateService.getOneObj(candidate);

        if (candidate == null) {
            return null;
        }
        String assignee = "";
        String candidateUser = candidate.getCandidateUser();
        String candidatePost = candidate.getCandidatePost();
        String candidateRole = candidate.getCandidateRole();

        // 先从候选用户获取用户，如果多个随机取一个
        if (Ft.String.isNotBlank(candidateUser)) {
            String[] split = candidateUser.split(",");
            if (split.length > 0) {
                assignee = split[0];
            }
        } else if (Ft.String.isNotBlank(candidatePost)) { // 从候选岗位
            Set<String> userIds = findUserByPostIds(candidatePost.split(","));
            assignee = userIds != null && userIds.size() > 0 ? userIds.stream().findFirst().get() : "";
        } else if (Ft.String.isNotBlank(candidateRole)) { // 从候选角色
            Set<String> userIds = findUserByRoleIds(candidateRole.split(","));
            assignee = userIds != null && userIds.size() > 0 ? userIds.stream().findFirst().get() : "";
        }
        return assignee;
    }

    /**
     * 获取代理人
     *
     * @param procDefId
     * @param nodeId
     * @return
     */
    public Set<String> getAssignees(String procDefId, String nodeId) {
        FwTaskCandidateBo candidate = new FwTaskCandidateBo();
        candidate.setProcDefId(procDefId);
        candidate.setNodeId(nodeId);
        candidate = taskCandidateService.getOneObj(candidate);

        if (candidate == null) {
            return null;
        }
        Set<String> assignees = new HashSet<>();
        String candidateUser = candidate.getCandidateUser();
        String candidatePost = candidate.getCandidatePost();
        String candidateRole = candidate.getCandidateRole();

        // 先从候选用户获取用户，如果多个随机取一个
        if (Ft.String.isNotBlank(candidateUser)) {
            String[] split = candidateUser.split(",");
            if (split.length > 0) {
                assignees.addAll(Arrays.asList(split));
            }
        }
        // 从候选岗位
        if (Ft.String.isNotBlank(candidatePost)) {
            assignees.addAll(findUserByPostIds(candidatePost.split(",")));
        }
        // 从候选角色
        if (Ft.String.isNotBlank(candidateRole)) {
            assignees.addAll(findUserByRoleIds(candidateRole.split(",")));
        }
        return assignees;
    }
}
